//
//  UITabBarControllerExample.swift
//  SwiftCode
//
//  Created by 于虎拴 on 2023/3/30.
//

import Foundation
import UIKit
import RxSwift

final class UITabBarControllerExample: ListViewController {
  override func getItemCount() -> Int {
    data.count
  }
  
  override func getItem(_ indexPath: IndexPath) -> Item {
    data[indexPath.row]
  }
  
  private lazy var data: [Item] = [
    // 适合 UITabBarController + UViewController
    .init(title: "UITabBarController", description: "系统样式", type: SystemTabBar.self),
    // 适合 UITabBarController + UINavigationController
    // modalPresentationStyle = .overCurrentContext，不能覆盖 TabBar，
    .init(title: "PartiallyCustomTabBar", description: "部分定制，继承 UITabBar", type: PartiallyCustomTabBar.self),
    // 适合 UITabBarController + UINavigationController
    // modalPresentationStyle = .overCurrentContext，能覆盖 TabBar，需要自定义 TabBar 下沉到 Child
    .init(title: "FullyCustomTabBar", description: "完全定制，继承 UIView", type: FullyCustomTabBar.self),
  ]
}

/// - TabBar 默认高度 83
final class SystemTabBar: UITabBarController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    
    tabBar.shadowImage = UIImage()
    tabBar.backgroundImage = UIImage()
    
    tabBar.tintColor = .black.withAlphaComponent(0.95)
    tabBar.unselectedItemTintColor = .black.withAlphaComponent(0.4)
    
    addChildren(TabBarItem.allCases)
  }
  
  func addChildren(_ items: [TabBarItem]) {
    items.forEach { item in
      if let controller = item.viewController {
        controller.tabBarItem = item.item
        addChild(UINavigationController(rootViewController: controller))
      }
    }
    
    // 默认 tab
    selectedIndex = 1
  }
}

/// - 自定义 TabBar
/// - TabBar 高度 94，重写 sizeThatFits 方法
final class PartiallyCustomTabBar: UITabBarController {
  override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    
    setValue(TabBar(), forKey: "tabBar")
    
    tabBar.shadowImage = UIImage()
    tabBar.backgroundImage = UIImage()
    
    tabBar.tintColor = .black.withAlphaComponent(0.95)
    tabBar.unselectedItemTintColor = .black.withAlphaComponent(0.4)
    
    addChildren(TabBarItem.allCases)
  }
  
  func addChildren(_ items: [TabBarItem]) {
    items.forEach { item in
      if let controller = item.viewController {
        controller.tabBarItem = item.item
        addChild(UINavigationController(rootViewController: controller))
      }
    }
    
    // 默认 tab
    selectedIndex = 1
  }
}

/// - 自定义 TabBar
/// - 需要自己处理事件
final class FullyCustomTabBar: UITabBarController {
  private let bag = DisposeBag()
  private let tabBarView = TabBarView()
  
  private var didSelectItemSubject = PublishSubject<UITabBarItem>()
  
  override var selectedIndex: Int {
    didSet {
      updateChild(selectedIndex)
    }
  }
  
  override func viewDidLoad() {
    view.backgroundColor = .white
    
    initView()
    initData()
  }
  
  private func initView() {
    super.tabBar.isHidden = true
    let tabBar = tabBarView
    
    tabBar.shadowImage = UIImage()
    tabBar.backgroundImage = UIImage()
    
    tabBar.tintColor = .black.withAlphaComponent(0.95)
    tabBar.unselectedItemTintColor = .black.withAlphaComponent(0.4)
    
    addChildren(TabBarItem.allCases)
  }
  
  func addChildren(_ items: [TabBarItem]) {
    tabBarView.items = items.map(\.item)
    items.forEach { item in
      if let controller = item.viewController {
        controller.tabBarItem = item.item
        addChild(UINavigationController(rootViewController: controller))
      }
    }
    
    // 默认 tab
    selectedIndex = 1
  }
  
  func updateChild(_ index: Int) {
    Timber.d(#function)
    tabBarView.selectedIndex = index
    let child = children[index]
    if let navigationController = child as? UINavigationController,
       let rootViewController = navigationController.children.first {
      rootViewController.view.addSubview(tabBarView)
      tabBarView.snp.remakeConstraints { make in
        make.height.equalTo(94)
        make.leading.trailing.equalToSuperview()
        make.bottom.equalToSuperview()
      }
    }
  }
  
  private func initData() {
    tabBarView.didSelectItem
      .asObservable()
      .debug()
      .bind(to: rx.selectedIndex)
      .disposed(by: bag)
  }
}

enum TabBarItem: String, CaseIterable {
  case avatar
  case party
  case chat
  case feed
  
  var item: UITabBarItem {
    switch self {
    case .avatar:
      return UITabBarItem(
        title: "Avatar",
        image: "tabbar_avatar".image?.withRenderingMode(.alwaysOriginal),
        selectedImage: "tabbar_avatar_select".image?.withRenderingMode(.alwaysOriginal)
      )
    case .party:
      return UITabBarItem(
        title: "Party",
        image: "tabbar_parties".image?.withRenderingMode(.alwaysOriginal),
        selectedImage: "tabbar_parties_select".image?.withRenderingMode(.alwaysOriginal)
      )
    case .chat:
      return UITabBarItem(
        title: "Chat",
        image: "tabbar_chat".image?.withRenderingMode(.alwaysOriginal),
        selectedImage: "tabbar_chat_select".image?.withRenderingMode(.alwaysOriginal)
      )
    case .feed:
      return UITabBarItem(
        title: "Feed",
        image: "tabbar_feed".image?.withRenderingMode(.alwaysOriginal),
        selectedImage: "tabbar_feed_select".image?.withRenderingMode(.alwaysOriginal)
      )
    }
  }
  
  var viewController: UIViewController? {
    let labelViewController = LabelViewController()
    labelViewController.label.text = self.rawValue.capitalized
    return labelViewController
  }
}

private extension String {
  var image: UIImage? {
    guard !isEmpty else { return nil }
    return UIImage(named: self, in: Bundle.main, with: nil)
  }
}

